package net;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import dataBase.Data;
import dataBase.DataBase;

public class ServerSystem {

    private static DataBase db = new DataBase();

    public static void main(String[] args) throws IOException {
        System.out.println("-----Course Selection System Server-----");
        @SuppressWarnings("resource")
        ServerSocket server = new ServerSocket(10000);

        while (true) {
            Socket socket = server.accept();
            System.out.print("#" + socket.getInetAddress() + "#\t");
            socket.setSoTimeout(10 * 1000);
            invoke(socket);
        }
    }

    private static void invoke(final Socket socket) throws IOException {
        new Thread(new Runnable() {
            public void run() {
                GZIPInputStream gzipis = null;
                ObjectInputStream ois = null;
                GZIPOutputStream gzipos = null;
                ObjectOutputStream oos = null;

                try {
                    gzipis = new GZIPInputStream(socket.getInputStream());
                    ois = new ObjectInputStream(gzipis);
                    gzipos = new GZIPOutputStream(socket.getOutputStream());
                    oos = new ObjectOutputStream(gzipos);

                    Object obj = ois.readObject();
                    NetCommand cmd = (NetCommand) obj;
                    System.out.println(cmd.getCmd());
                    Object re = runCmd(cmd);
                    oos.writeObject(re);
                    oos.flush();
                    gzipos.finish();
                } catch (IOException ex) {
                    System.err.println("Internet IO Error!");
                } catch (ClassNotFoundException ex) {
                    System.err.println("ClassNotFoundException!");
                } finally {
                    try {
                        ois.close();
                    } catch (Exception ex) {
                    }
                    try {
                        oos.close();
                    } catch (Exception ex) {
                    }
                    try {
                        socket.close();
                    } catch (Exception ex) {
                    }
                }
            }
        }).start();
    }

    private static Object runCmd(NetCommand netCmd) {
        String[] cmd = netCmd.getCmd().split(" ");
        Object obj = netCmd.getObj();

        switch (cmd[0]) {
        case "start":
            return "start";
        case "containsKey":
            return db.containsKey(cmd[1], cmd[2]);
        case "getData":
            return db.getData(cmd[1], cmd[2]);
        case "putData":
            db.putData(cmd[1], cmd[2], (Data) obj);
            return 0;
        case "deleteData":
            db.deleteData(cmd[1], cmd[2]);
            return 0;
        case "getDataList":
            return db.getDataList(cmd[1]);
        }
        return null;
    }
}
